package com.nodusk.timeline.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nodusk.timeline.common.Result;
import com.nodusk.timeline.entity.Blog;
import com.nodusk.timeline.service.BlogService;
import com.nodusk.timeline.util.ShiroUtil;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.time.LocalDateTime;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 今何许
 * @since 2021-08-14
 */
@RestController
@RequestMapping
public class BlogController {

    @Autowired
    private RestHighLevelClient client;
    @Autowired
    private BlogService blogService;

    @GetMapping("/blogs")
    public Result list(@RequestParam(defaultValue = "1") Integer currentPage) {

        Page page = new Page(currentPage, 5);
        IPage pageData = blogService.page(page, new QueryWrapper<Blog>().orderByDesc("created"));

        return Result.success(pageData);
    }

    @GetMapping("/blog/{id}")
    public Result detail(@PathVariable(name = "id") Long id) {
        Blog blog = blogService.getById(id);
        Assert.notNull(blog, "该博客已被删除");
        return Result.success(blog);
    }

    @RequiresAuthentication
    @PostMapping("/blog/edit")
    public Result edit(@Validated @RequestBody Blog blog) throws IOException {
        Blog temp = null;
        boolean saveOrUpdate;
        String status = "";
        if (blog.getId() != null) {
            temp = blogService.getById(blog.getId());
            // 只能编辑自己的文章
            System.out.println(ShiroUtil.getProfile().getId());
            Assert.isTrue(temp.getUserId().longValue() == ShiroUtil.getProfile().getId().longValue(), "没有权限编辑");
        } else {
            temp = new Blog();
            temp.setUserId(ShiroUtil.getProfile().getId());
            temp.setCreated(LocalDateTime.now());
            temp.setStatus(0);
            BeanUtil.copyProperties(blog, temp, "id", "userId", "created", "status");
            saveOrUpdate = blogService.insertBlog(temp);
            status = addEsBlog(temp);
            if (saveOrUpdate && status.equalsIgnoreCase("CREATED")) {
                return Result.success(null);
            } else {
                return Result.fail("操作失败");
            }
        }
        BeanUtil.copyProperties(blog, temp, "id", "userId", "created", "status");
        saveOrUpdate = blogService.saveOrUpdate(temp);
        status = updateEsBlog(temp);
        if (saveOrUpdate && status.equalsIgnoreCase("OK")) {
            return Result.success(null);
        } else {
            return Result.fail("操作失败");
        }

    }

    /**
     * 更新ElasticSearch中Blog
     */
    private String updateEsBlog(Blog blog) throws IOException {
        UpdateRequest request = new UpdateRequest("blogs", String.valueOf(blog.getId()));
        request.timeout("2s");
        request.doc(JSON.toJSONString(blog), XContentType.JSON);
        UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
        System.out.println("更新：" + response.status()); //成功返回 OK
        System.out.println(response.toString());
        return response.status().toString();
    }

    /**
     * 添加Blog到ElasticSearch
     */
    private String addEsBlog(Blog blog) throws IOException {
        IndexRequest request = new IndexRequest("blogs");
        request.id(String.valueOf(blog.getId())).timeout(TimeValue.timeValueSeconds(2));//设置id，1秒超时
        request.timeout("1s");
        // 数据转换成json 放入请求
        request.source(JSON.toJSONString(blog), XContentType.JSON);
        //将请求发出去,获取响应结果
        IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
        System.out.println("添加：" + indexResponse.status()); // 返回当前操作的类型：CREATE
        System.out.println(indexResponse.toString()); //响应内容
        return indexResponse.status().toString();
    }
}
